{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fine-Tuning OpenAI Models for Retrieval Augmented Generation (RAG) with Qdrant and Few-Shot Learning\n",
    "\n",
    "The aim of this notebook is to walk through a comprehensive example of how to fine-tune OpenAI models for Retrieval Augmented Generation (RAG). \n",
    "\n",
    "We will also be integrating Qdrant and Few-Shot Learning to boost the model's performance and reduce hallucinations. This could serve as a practical guide for ML practitioners, data scientists, and AI Engineers interested in leveraging the power of OpenAI models for specific use-cases. 🤩\n",
    "\n",
    "## Why should you read this blog?\n",
    "\n",
    "You want to learn how to \n",
    "- [Fine-tune OpenAI models](https://platform.openai.com/docs/guides/fine-tuning/) for specific use-cases\n",
    "- Use [Qdrant](https://qdrant.tech/documentation/) to improve the performance of your RAG model\n",
    "- Use fine-tuning to improve the correctness of your RAG model and reduce hallucinations\n",
    "\n",
    "To begin, we've selected a dataset where we've a guarantee that the retrieval is perfect. We've selected a subset of the [SQuAD](https://rajpurkar.github.io/SQuAD-explorer/) dataset, which is a collection of questions and answers about Wikipedia articles. We've also included samples where the answer is not present in the context, to demonstrate how RAG handles this case.\n",
    "\n",
    "## Table of Contents\n",
    "1. Setting up the Environment\n",
    "\n",
    "### Section A: Zero-Shot Learning\n",
    "2. Data Preparation: SQuADv2 Dataset\n",
    "3. Answering using Base gpt-3.5-turbo-0613 model\n",
    "4. Fine-tuning and Answering using Fine-tuned model\n",
    "5. **Evaluation**: How well does the model perform?\n",
    "\n",
    "### Section B: Few-Shot Learning\n",
    "\n",
    "6. Using Qdrant to Improve RAG Prompt\n",
    "7. Fine-Tuning OpenAI Model with Qdrant\n",
    "8. Evaluation\n",
    "\n",
    "9. **Conclusion**\n",
    "    - Aggregate Results\n",
    "    - Observations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Terms, Definitions, and References\n",
    "\n",
    "**Retrieval Augmented Generation (RAG)?**\n",
    "The phrase Retrieval Augmented Generation (RAG) comes from a [recent paper](https://arxiv.org/abs/2005.11401) by Lewis et al. from Facebook AI. The idea is to use a pre-trained language model (LM) to generate text, but to use a separate retrieval system to find relevant documents to condition the LM on. \n",
    "\n",
    "**What is Qdrant?**\n",
    "Qdrant is an open-source vector search engine that allows you to search for similar vectors in a large dataset. It is built in Rust and here we'll use the Python client to interact with it. This is the Retrieval part of RAG.\n",
    "\n",
    "**What is Few-Shot Learning?**\n",
    "Few-shot learning is a type of machine learning where the model is \"improved\" via training or fine-tuning on a small amount of data. In this case, we'll use it to fine-tune the RAG model on a small number of examples from the SQuAD dataset. This is the Augmented part of RAG.\n",
    "\n",
    "**What is Zero-Shot Learning?**\n",
    "Zero-shot learning is a type of machine learning where the model is \"improved\" via training or fine-tuning without any dataset specific information. \n",
    "\n",
    "**What is Fine-Tuning?**\n",
    "Fine-tuning is a type of machine learning where the model is \"improved\" via training or fine-tuning on a small amount of data. In this case, we'll use it to fine-tune the RAG model on a small number of examples from the SQuAD dataset. The LLM is what makes the Generation part of RAG."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Setting Up the Environment\n",
    "\n",
    "### Install and Import Dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install pandas openai tqdm tenacity scikit-learn tiktoken python-dotenv seaborn --upgrade --quiet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import os\n",
    "import time\n",
    "\n",
    "import pandas as pd\n",
    "from openai import OpenAI\n",
    "import tiktoken\n",
    "import seaborn as sns\n",
    "from tenacity import retry, wait_exponential\n",
    "from tqdm import tqdm\n",
    "from collections import defaultdict\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "tqdm.pandas()\n",
    "\n",
    "client = OpenAI(api_key=os.environ.get(\"OPENAI_API_KEY\", \"<your OpenAI API key if not set as env var>\"))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Set your keys\n",
    "Get your OpenAI keys [here](https://platform.openai.com/account/api-keys) and Qdrant keys after making a free cluster [here](https://cloud.qdrant.io/login)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.environ[\"QDRANT_URL\"] = \"https://xxx.cloud.qdrant.io:6333\"\n",
    "os.environ[\"QDRANT_API_KEY\"] = \"xxx\""
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Section A\n",
    "\n",
    "## 2. Data Preparation: SQuADv2 Data Subsets\n",
    "\n",
    "For the purpose of demonstration, we'll make small slices from the train and validation splits of the [SQuADv2](https://rajpurkar.github.io/SQuAD-explorer/) dataset. This dataset has questions and contexts where the answer is not present in the context, to help us evaluate how LLM handles this case.\n",
    "\n",
    "We'll read the data from the JSON files and create a dataframe with the following columns: `question`, `context`, `answer`, `is_impossible`.\n",
    "\n",
    "### Download the Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !mkdir -p local_cache\n",
    "# !wget https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json -O local_cache/train.json\n",
    "# !wget https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json -O local_cache/dev.json"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Read JSON to DataFrame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def json_to_dataframe_with_titles(json_data):\n",
    "    qas = []\n",
    "    context = []\n",
    "    is_impossible = []\n",
    "    answers = []\n",
    "    titles = []\n",
    "\n",
    "    for article in json_data['data']:\n",
    "        title = article['title']\n",
    "        for paragraph in article['paragraphs']:\n",
    "            for qa in paragraph['qas']:\n",
    "                qas.append(qa['question'].strip())\n",
    "                context.append(paragraph['context'])\n",
    "                is_impossible.append(qa['is_impossible'])\n",
    "                \n",
    "                ans_list = []\n",
    "                for ans in qa['answers']:\n",
    "                    ans_list.append(ans['text'])\n",
    "                answers.append(ans_list)\n",
    "                titles.append(title)\n",
    "\n",
    "    df = pd.DataFrame({'title': titles, 'question': qas, 'context': context, 'is_impossible': is_impossible, 'answers': answers})\n",
    "    return df\n",
    "\n",
    "def get_diverse_sample(df, sample_size=100, random_state=42):\n",
    "    \"\"\"\n",
    "    Get a diverse sample of the dataframe by sampling from each title\n",
    "    \"\"\"\n",
    "    sample_df = df.groupby(['title', 'is_impossible']).apply(lambda x: x.sample(min(len(x), max(1, sample_size // 50)), random_state=random_state)).reset_index(drop=True)\n",
    "    \n",
    "    if len(sample_df) < sample_size:\n",
    "        remaining_sample_size = sample_size - len(sample_df)\n",
    "        remaining_df = df.drop(sample_df.index).sample(remaining_sample_size, random_state=random_state)\n",
    "        sample_df = pd.concat([sample_df, remaining_df]).sample(frac=1, random_state=random_state).reset_index(drop=True)\n",
    "\n",
    "    return sample_df.sample(min(sample_size, len(sample_df)), random_state=random_state).reset_index(drop=True)\n",
    "\n",
    "train_df = json_to_dataframe_with_titles(json.load(open('local_cache/train.json')))\n",
    "val_df = json_to_dataframe_with_titles(json.load(open('local_cache/dev.json')))\n",
    "\n",
    "df = get_diverse_sample(val_df, sample_size=100, random_state=42)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Answering using Base gpt-3.5-turbo-0613 model\n",
    "\n",
    "### 3.1 Zero Shot Prompt\n",
    "\n",
    "Let's start by using the base gpt-3.5-turbo-0613 model to answer the questions. This prompt is a simple concatenation of the question and context, with a separator token in between: `\\n\\n`. We've a simple instruction part of the prompt: \n",
    "\n",
    "> Answer the following Question based on the Context only. Only answer from the Context. If you don't know the answer, say 'I don't know'.\n",
    "\n",
    "Other prompts are possible, but this is a good starting point. We'll use this prompt to answer the questions in the validation set. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function to get prompt messages\n",
    "def get_prompt(row):\n",
    "    return [\n",
    "        {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": f\"\"\"Answer the following Question based on the Context only. Only answer from the Context. If you don't know the answer, say 'I don't know'.\n",
    "    Question: {row.question}\\n\\n\n",
    "    Context: {row.context}\\n\\n\n",
    "    Answer:\\n\"\"\",\n",
    "        },\n",
    "    ]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 Answering using Zero Shot Prompt\n",
    "\n",
    "Next, you'll need some re-usable functions which make an OpenAI API Call and return the answer. You'll use the `ChatCompletion.create` endpoint of the API, which takes a prompt and returns the completed text."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function with tenacity for retries\n",
    "@retry(wait=wait_exponential(multiplier=1, min=2, max=6))\n",
    "def api_call(messages, model):\n",
    "    return client.chat.completions.create(\n",
    "        model=model,\n",
    "        messages=messages,\n",
    "        stop=[\"\\n\\n\"],\n",
    "        max_tokens=100,\n",
    "        temperature=0.0,\n",
    "    )\n",
    "\n",
    "\n",
    "# Main function to answer question\n",
    "def answer_question(row, prompt_func=get_prompt, model=\"gpt-3.5-turbo\"):\n",
    "    messages = prompt_func(row)\n",
    "    response = api_call(messages, model)\n",
    "    return response.choices[0].message.content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "⏰ **Time to run: ~3 min**, 🛜 Needs Internet Connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use progress_apply with tqdm for progress bar\n",
    "df[\"generated_answer\"] = df.progress_apply(answer_question, axis=1)\n",
    "df.to_json(\"local_cache/100_val.json\", orient=\"records\", lines=True)\n",
    "df = pd.read_json(\"local_cache/100_val.json\", orient=\"records\", lines=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>title</th>\n",
       "      <th>question</th>\n",
       "      <th>context</th>\n",
       "      <th>is_impossible</th>\n",
       "      <th>answers</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Scottish_Parliament</td>\n",
       "      <td>What consequence of establishing the Scottish ...</td>\n",
       "      <td>A procedural consequence of the establishment ...</td>\n",
       "      <td>False</td>\n",
       "      <td>[able to vote on domestic legislation that app...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Imperialism</td>\n",
       "      <td>Imperialism is less often associated with whic...</td>\n",
       "      <td>The principles of imperialism are often genera...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Economic_inequality</td>\n",
       "      <td>What issues can't prevent women from working o...</td>\n",
       "      <td>When a person’s capabilities are lowered, they...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Southern_California</td>\n",
       "      <td>What county are Los Angeles, Orange, San Diego...</td>\n",
       "      <td>Its counties of Los Angeles, Orange, San Diego...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>French_and_Indian_War</td>\n",
       "      <td>When was the deportation of Canadians?</td>\n",
       "      <td>Britain gained control of French Canada and Ac...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>95</th>\n",
       "      <td>Geology</td>\n",
       "      <td>In the layered Earth model, what is the inner ...</td>\n",
       "      <td>Seismologists can use the arrival times of sei...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>96</th>\n",
       "      <td>Prime_number</td>\n",
       "      <td>What type of value would the Basel function ha...</td>\n",
       "      <td>The zeta function is closely related to prime ...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>97</th>\n",
       "      <td>Fresno,_California</td>\n",
       "      <td>What does the San Joaquin Valley Railroad cros...</td>\n",
       "      <td>Passenger rail service is provided by Amtrak S...</td>\n",
       "      <td>True</td>\n",
       "      <td>[]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>98</th>\n",
       "      <td>Victoria_(Australia)</td>\n",
       "      <td>What party rules in Melbourne's inner regions?</td>\n",
       "      <td>The centre-left Australian Labor Party (ALP), ...</td>\n",
       "      <td>False</td>\n",
       "      <td>[The Greens, Australian Greens, Greens]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>99</th>\n",
       "      <td>Immune_system</td>\n",
       "      <td>The speed of the killing response of the human...</td>\n",
       "      <td>In humans, this response is activated by compl...</td>\n",
       "      <td>False</td>\n",
       "      <td>[signal amplification, signal amplification, s...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>100 rows × 5 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                    title                                           question  \\\n",
       "0     Scottish_Parliament  What consequence of establishing the Scottish ...   \n",
       "1             Imperialism  Imperialism is less often associated with whic...   \n",
       "2     Economic_inequality  What issues can't prevent women from working o...   \n",
       "3     Southern_California  What county are Los Angeles, Orange, San Diego...   \n",
       "4   French_and_Indian_War             When was the deportation of Canadians?   \n",
       "..                    ...                                                ...   \n",
       "95                Geology  In the layered Earth model, what is the inner ...   \n",
       "96           Prime_number  What type of value would the Basel function ha...   \n",
       "97     Fresno,_California  What does the San Joaquin Valley Railroad cros...   \n",
       "98   Victoria_(Australia)     What party rules in Melbourne's inner regions?   \n",
       "99          Immune_system  The speed of the killing response of the human...   \n",
       "\n",
       "                                              context  is_impossible  \\\n",
       "0   A procedural consequence of the establishment ...          False   \n",
       "1   The principles of imperialism are often genera...           True   \n",
       "2   When a person’s capabilities are lowered, they...           True   \n",
       "3   Its counties of Los Angeles, Orange, San Diego...           True   \n",
       "4   Britain gained control of French Canada and Ac...           True   \n",
       "..                                                ...            ...   \n",
       "95  Seismologists can use the arrival times of sei...           True   \n",
       "96  The zeta function is closely related to prime ...           True   \n",
       "97  Passenger rail service is provided by Amtrak S...           True   \n",
       "98  The centre-left Australian Labor Party (ALP), ...          False   \n",
       "99  In humans, this response is activated by compl...          False   \n",
       "\n",
       "                                              answers  \n",
       "0   [able to vote on domestic legislation that app...  \n",
       "1                                                  []  \n",
       "2                                                  []  \n",
       "3                                                  []  \n",
       "4                                                  []  \n",
       "..                                                ...  \n",
       "95                                                 []  \n",
       "96                                                 []  \n",
       "97                                                 []  \n",
       "98            [The Greens, Australian Greens, Greens]  \n",
       "99  [signal amplification, signal amplification, s...  \n",
       "\n",
       "[100 rows x 5 columns]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Fine-tuning and Answering using Fine-tuned model\n",
    "\n",
    "For the complete fine-tuning process, please refer to the [OpenAI Fine-Tuning Docs](https://platform.openai.com/docs/guides/fine-tuning/use-a-fine-tuned-model).\n",
    "\n",
    "### 4.1 Prepare the Fine-Tuning Data\n",
    "\n",
    "We need to prepare the data for fine-tuning. We'll use a few samples from train split of same dataset as before, but we'll add the answer to the context. This will help the model learn to retrieve the answer from the context. \n",
    "\n",
    "Our instruction prompt is the same as before, and so is the system prompt. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def dataframe_to_jsonl(df):\n",
    "    def create_jsonl_entry(row):\n",
    "        answer = row[\"answers\"][0] if row[\"answers\"] else \"I don't know\"\n",
    "        messages = [\n",
    "            {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": f\"\"\"Answer the following Question based on the Context only. Only answer from the Context. If you don't know the answer, say 'I don't know'.\n",
    "            Question: {row.question}\\n\\n\n",
    "            Context: {row.context}\\n\\n\n",
    "            Answer:\\n\"\"\",\n",
    "            },\n",
    "            {\"role\": \"assistant\", \"content\": answer},\n",
    "        ]\n",
    "        return json.dumps({\"messages\": messages})\n",
    "\n",
    "    jsonl_output = df.apply(create_jsonl_entry, axis=1)\n",
    "    return \"\\n\".join(jsonl_output)\n",
    "\n",
    "train_sample = get_diverse_sample(train_df, sample_size=100, random_state=42)\n",
    "\n",
    "with open(\"local_cache/100_train.jsonl\", \"w\") as f:\n",
    "    f.write(dataframe_to_jsonl(train_sample))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Tip: 💡 Verify the Fine-Tuning Data**\n",
    "\n",
    "You can see this [cookbook](https://github.com/openai/openai-cookbook/blob/main/examples/Chat_finetuning_data_prep.ipynb) for more details on how to prepare the data for fine-tuning.\n",
    "\n",
    "### 4.2 Fine-Tune OpenAI Model\n",
    "\n",
    "If you're new to OpenAI Model Fine-Tuning, please refer to the [How to finetune Chat models](https://github.com/openai/openai-cookbook/blob/448a0595b84ced3bebc9a1568b625e748f9c1d60/examples/How_to_finetune_chat_models.ipynb) notebook. You can also refer to the [OpenAI Fine-Tuning Docs](platform.openai.com/docs/guides/fine-tuning/use-a-fine-tuned-model) for more details."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "class OpenAIFineTuner:\n",
    "    \"\"\"\n",
    "    Class to fine tune OpenAI models\n",
    "    \"\"\"\n",
    "    def __init__(self, training_file_path, model_name, suffix):\n",
    "        self.training_file_path = training_file_path\n",
    "        self.model_name = model_name\n",
    "        self.suffix = suffix\n",
    "        self.file_object = None\n",
    "        self.fine_tuning_job = None\n",
    "        self.model_id = None\n",
    "\n",
    "    def create_openai_file(self):\n",
    "        self.file_object = client.files.create(\n",
    "            file=open(self.training_file_path, \"r\"),\n",
    "            purpose=\"fine-tune\",\n",
    "        )\n",
    "\n",
    "    def wait_for_file_processing(self, sleep_time=20):\n",
    "        while self.file_object.status != 'processed':\n",
    "            time.sleep(sleep_time)\n",
    "            self.file_object.refresh()\n",
    "            print(\"File Status: \", self.file_object.status)\n",
    "\n",
    "    def create_fine_tuning_job(self):\n",
    "        self.fine_tuning_job = client.fine_tuning.jobs.create(\n",
    "            training_file=self.file_object[\"id\"],\n",
    "            model=self.model_name,\n",
    "            suffix=self.suffix,\n",
    "        )\n",
    "\n",
    "    def wait_for_fine_tuning(self, sleep_time=45):\n",
    "        while self.fine_tuning_job.status != 'succeeded':\n",
    "            time.sleep(sleep_time)\n",
    "            self.fine_tuning_job.refresh()\n",
    "            print(\"Job Status: \", self.fine_tuning_job.status)\n",
    "\n",
    "    def retrieve_fine_tuned_model(self):\n",
    "        self.model_id = client.fine_tuning.jobs.retrieve(self.fine_tuning_job[\"id\"]).fine_tuned_model\n",
    "        return self.model_id\n",
    "\n",
    "    def fine_tune_model(self):\n",
    "        self.create_openai_file()\n",
    "        self.wait_for_file_processing()\n",
    "        self.create_fine_tuning_job()\n",
    "        self.wait_for_fine_tuning()\n",
    "        return self.retrieve_fine_tuned_model()\n",
    "\n",
    "fine_tuner = OpenAIFineTuner(\n",
    "        training_file_path=\"local_cache/100_train.jsonl\",\n",
    "        model_name=\"gpt-3.5-turbo\",\n",
    "        suffix=\"100trn20230907\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "⏰ **Time to run: ~10-20 minutes**, 🛜 Needs Internet Connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_id = fine_tuner.fine_tune_model()\n",
    "model_id"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4.2.1 Try out the Fine-Tuned Model\n",
    "\n",
    "Let's try out the fine-tuned model on the same validation set as before. You'll use the same prompt as before, but you will use the fine-tuned model instead of the base model. Before you do that, you can make a simple call to get a sense of how the fine-tuned model is doing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "completion = client.chat.completions.create(\n",
    "    model=model_id,\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
    "        {\"role\": \"user\", \"content\": \"Hello!\"},\n",
    "        {\"role\": \"assistant\", \"content\": \"Hi, how can I help you today?\"},\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Can you answer the following question based on the given context? If not, say, I don't know:\\n\\nQuestion: What is the capital of France?\\n\\nContext: The capital of Mars is Gaia. Answer:\",\n",
    "        },\n",
    "    ],\n",
    ")\n",
    "\n",
    "print(completion.choices[0].message)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 Answer Using the Fine-Tuned Model\n",
    "\n",
    "This is the same as before, but you'll use the fine-tuned model instead of the base model.\n",
    "\n",
    "⏰ **Time to run: ~5 min**, 🛜 Needs Internet Connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"ft_generated_answer\"] = df.progress_apply(answer_question, model=model_id, axis=1)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Evaluation: How well does the model perform?\n",
    "\n",
    "To evaluate the model's performance, compare the predicted answer to the actual answers -- if any of the actual answers are present in the predicted answer, then it's a match. We've also created error categories to help you understand where the model is struggling.\n",
    "\n",
    "When we know that a correct answer exists in the context, we can measure the model's performance, there are 3 possible outcomes:\n",
    "\n",
    "1. ✅ **Answered Correctly**: The model responded the correct answer. It may have also included other answers that were not in the context.\n",
    "2. ❎ **Skipped**: The model responded with \"I don't know\" (IDK) while the answer was present in the context. It's better than giving the wrong answer. It's better for the model say \"I don't know\" than giving the wrong answer. In our design, we know that a true answer exists and hence we're able to measure it -- this is not always the case. *This is a model error*. We exclude this from the overall error rate. \n",
    "3. ❌ **Wrong**: The model responded with an incorrect answer. **This is a model ERROR.**\n",
    "\n",
    "When we know that a correct answer does not exist in the context, we can measure the model's performance, there are 2 possible outcomes:\n",
    "\n",
    "4. ❌ **Hallucination**: The model responded with an answer, when \"I don't know\" was expected. **This is a model ERROR.** \n",
    "5. ✅ **I don't know**: The model responded with \"I don't know\" (IDK) and the answer was not present in the context. **This is a model WIN.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "class Evaluator:\n",
    "    def __init__(self, df):\n",
    "        self.df = df\n",
    "        self.y_pred = pd.Series()  # Initialize as empty Series\n",
    "        self.labels_answer_expected = [\"✅ Answered Correctly\", \"❎ Skipped\", \"❌ Wrong Answer\"]\n",
    "        self.labels_idk_expected = [\"❌ Hallucination\", \"✅ I don't know\"]\n",
    "\n",
    "    def _evaluate_answer_expected(self, row, answers_column):\n",
    "        generated_answer = row[answers_column].lower()\n",
    "        actual_answers = [ans.lower() for ans in row[\"answers\"]]\n",
    "        return (\n",
    "            \"✅ Answered Correctly\" if any(ans in generated_answer for ans in actual_answers)\n",
    "            else \"❎ Skipped\" if generated_answer == \"i don't know\"\n",
    "            else \"❌ Wrong Answer\"\n",
    "        )\n",
    "\n",
    "    def _evaluate_idk_expected(self, row, answers_column):\n",
    "        generated_answer = row[answers_column].lower()\n",
    "        return (\n",
    "            \"❌ Hallucination\" if generated_answer != \"i don't know\"\n",
    "            else \"✅ I don't know\"\n",
    "        )\n",
    "\n",
    "    def _evaluate_single_row(self, row, answers_column):\n",
    "        is_impossible = row[\"is_impossible\"]\n",
    "        return (\n",
    "            self._evaluate_answer_expected(row, answers_column) if not is_impossible\n",
    "            else self._evaluate_idk_expected(row, answers_column)\n",
    "        )\n",
    "\n",
    "    def evaluate_model(self, answers_column=\"generated_answer\"):\n",
    "        self.y_pred = pd.Series(self.df.apply(self._evaluate_single_row, answers_column=answers_column, axis=1))\n",
    "        freq_series = self.y_pred.value_counts()\n",
    "        \n",
    "        # Counting rows for each scenario\n",
    "        total_answer_expected = len(self.df[self.df['is_impossible'] == False])\n",
    "        total_idk_expected = len(self.df[self.df['is_impossible'] == True])\n",
    "        \n",
    "        freq_answer_expected = (freq_series / total_answer_expected * 100).round(2).reindex(self.labels_answer_expected, fill_value=0)\n",
    "        freq_idk_expected = (freq_series / total_idk_expected * 100).round(2).reindex(self.labels_idk_expected, fill_value=0)\n",
    "        return freq_answer_expected.to_dict(), freq_idk_expected.to_dict()\n",
    "\n",
    "    def print_eval(self):\n",
    "        answer_columns=[\"generated_answer\", \"ft_generated_answer\"]\n",
    "        baseline_correctness, baseline_idk = self.evaluate_model()\n",
    "        ft_correctness, ft_idk = self.evaluate_model(self.df, answer_columns[1])\n",
    "        print(\"When the model should answer correctly:\")\n",
    "        eval_df = pd.merge(\n",
    "            baseline_correctness.rename(\"Baseline\"),\n",
    "            ft_correctness.rename(\"Fine-Tuned\"),\n",
    "            left_index=True,\n",
    "            right_index=True,\n",
    "        )\n",
    "        print(eval_df)\n",
    "        print(\"\\n\\n\\nWhen the model should say 'I don't know':\")\n",
    "        eval_df = pd.merge(\n",
    "            baseline_idk.rename(\"Baseline\"),\n",
    "            ft_idk.rename(\"Fine-Tuned\"),\n",
    "            left_index=True,\n",
    "            right_index=True,\n",
    "        )\n",
    "        print(eval_df)\n",
    "    \n",
    "    def plot_model_comparison(self, answer_columns=[\"generated_answer\", \"ft_generated_answer\"], scenario=\"answer_expected\", nice_names=[\"Baseline\", \"Fine-Tuned\"]):\n",
    "        \n",
    "        results = []\n",
    "        for col in answer_columns:\n",
    "            answer_expected, idk_expected = self.evaluate_model(col)\n",
    "            if scenario == \"answer_expected\":\n",
    "                results.append(answer_expected)\n",
    "            elif scenario == \"idk_expected\":\n",
    "                results.append(idk_expected)\n",
    "            else:\n",
    "                raise ValueError(\"Invalid scenario\")\n",
    "        \n",
    "        \n",
    "        results_df = pd.DataFrame(results, index=nice_names)\n",
    "        if scenario == \"answer_expected\":\n",
    "            results_df = results_df.reindex(self.labels_answer_expected, axis=1)\n",
    "        elif scenario == \"idk_expected\":\n",
    "            results_df = results_df.reindex(self.labels_idk_expected, axis=1)\n",
    "        \n",
    "        melted_df = results_df.reset_index().melt(id_vars='index', var_name='Status', value_name='Frequency')\n",
    "        sns.set_theme(style=\"whitegrid\", palette=\"icefire\")\n",
    "        g = sns.catplot(data=melted_df, x='Frequency', y='index', hue='Status', kind='bar', height=5, aspect=2)\n",
    "\n",
    "        # Annotating each bar\n",
    "        for p in g.ax.patches:\n",
    "            g.ax.annotate(f\"{p.get_width():.0f}%\", (p.get_width()+5, p.get_y() + p.get_height() / 2),\n",
    "                        textcoords=\"offset points\",\n",
    "                        xytext=(0, 0),\n",
    "                        ha='center', va='center')\n",
    "        plt.ylabel(\"Model\")\n",
    "        plt.xlabel(\"Percentage\")\n",
    "        plt.xlim(0, 100)\n",
    "        plt.tight_layout()\n",
    "        plt.title(scenario.replace(\"_\", \" \").title())\n",
    "        plt.show()\n",
    "\n",
    "\n",
    "# Compare the results by merging into one dataframe\n",
    "evaluator = Evaluator(df)\n",
    "# evaluator.evaluate_model(answers_column=\"ft_generated_answer\")\n",
    "# evaluator.plot_model_comparison([\"generated_answer\", \"ft_generated_answer\"], scenario=\"answer_expected\", nice_names=[\"Baseline\", \"Fine-Tuned\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optionally, save the results to a JSON file\n",
    "df.to_json(\"local_cache/100_val_ft.json\", orient=\"records\", lines=True)\n",
    "df = pd.read_json(\"local_cache/100_val_ft.json\", orient=\"records\", lines=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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/s719vbWtGnTdOXKFT158sRy/0yZMr3yuT4U/M0PAAAAIFaeL+Hp2bOnSpYsqUmTJun8+fMaPXq0Ll26pIULF+rhw4dKnDjxC+cmTpxYjx49kiR5eXmpZcuWqlu3rsxms+rUqaPy5ctr8eLFcnZ2VsWKFTV16lStWrVKrq6u6tOnj9zc3OL0WQHEjq+vr27fvq1z584pJCTEakld8eLFNWbMGB06dEjJkiWTh4eH1bkJEya0vDabzS+9vtlstgq1/23WVIIECf7z3k7BwcGSpOrVq79Qy08//aSCBQv+672f9/X29ta2bdu0a9cu7dmzRytXrtTkyZM1ffp0+fr6yt/fX0OGDNHFixd1/fp1FSpUSD4+Ptq3b58uX76sAgUKKEWKFLp48aIkaezYsVbh28tq+PsM1g8VM60AAAAAxMrzGQQeHh4aPHiwZQZB//79dejQIe3ateuV/9CUns2SeK5169Y6dOiQDh06pN69eyssLEyBgYHq3LmztmzZonnz5mnEiBHKmjWrOnTo8L4fDcA78sknnyh79uz66aefFBMTY7V3VLFixXT9+nWtX79evr6+/7rvkru7ux4+fGg1q8psNuvgwYPKli3bG9WSM2dOPXz40Gpj9rt37+rChQsv7X/ixAmdPHlSLVu21MqVKy1fq1atUokSJbRhwwbdvXv3je49fvx4HTx4UP7+/urdu7fWr18vNzc3rV+/XpJUokQJ3bt3T3PnzlXevHnl7OysokWLau/evfrtt9/k7+8vScqSJYvs7e119epVffbZZ5avbdu2acaMGR/s3lWv8nE9DQAAAIA483wGVenSpa3an2+gfuLECSVJkkSPHz9+4dxHjx4padKkVm0ODg6WWQKzZs2Su7u7fH19tX79epUtW1YeHh5q2rSpfv/9d125cuV9PBKA96BIkSJavny5ChUqZDX759NPP1WOHDm0bt06y7LBVylevLhy5cqlTp06KSQkROfOndPAgQN15swZNWzY8I3q8PHxUd68edW1a1cdOXJEp06dUufOnRUeHm4Voj8XHBysRIkSqXHjxpa9rJ5/NWvWTJGRkZaZWK9z6dIl9evXT3v27NGVK1e0fv16Xb16Vd7e3pKeLSUsWLCgFi9eLF9fX0nPZqlduHBBR48etYRWSZMmVZ06dTRu3DitWrVKly5d0rJlyzRixAh9+umnb1TL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",
      "text/plain": [
       "<Figure size 1203.25x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluator.plot_model_comparison([\"generated_answer\", \"ft_generated_answer\"], scenario=\"answer_expected\", nice_names=[\"Baseline\", \"Fine-Tuned\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that the fine-tuned model skips questions more often -- and makes fewer mistakes. This is because the fine-tuned model is more conservative and skips questions when it's not sure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABIAAAAH4CAYAAAAy4ZZRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAABWnElEQVR4nO3dd3yN9///8echkpgxG1qrgggJYseMoLYWpWpvJTVLjNpalNRKaKg9i4rR6UvVrCbErJWWGLE3kRBJzu8PP+fT00ityEkvj/vtllvPeb+v8boO76bn2ff1vkxms9ksAAAAAAAAGFYaWxcAAAAAAACAV4sACAAAAAAAwOAIgAAAAAAAAAyOAAgAAAAAAMDgCIAAAAAAAAAMjgAIAAAAAADA4AiAAAAAAAAADI4ACAAAAAAAwOAIgAAAAGBhNpttXQIAAHgFCIAAAMBrISAgQK6urk/dzsfHR0OGDLG8d3V1VUBAwHOdq127dnJ1dU3yp2XLls9df0oICwtT9+7dk+VYwcHBcnV1VWRkZLIcDwAAvBw7WxcAAABgRMWLF9eoUaOe2JcxY8YUrubZrF69WidPnrR1GQAA4BUgAAIAAHgFMmXKpNKlS9u6DAAAAEncAgYAAF5jx48fV6dOneTp6amaNWtqw4YNT91nxowZcnNz09q1a1/6/L/88kuiW8xOnjypkiVLatiwYZIe3brm4+OjX3/9VfXq1VOpUqXUsmVLhYSEWB3r1q1bGjlypCpXriwPDw+1bNlSu3fvttomNjZW06ZNU61atVSyZEk1atTIch1DhgzR2rVrdf78ebm6uio4OFiS9ODBA02aNEk1atSQu7u7GjdurB9//NHquAkJCZo1a5a8vb1VqlQp9erVS7dv337pzwcAACQfZgABAIDX0uXLl9W2bVsVLFhQkydPVlRUlPz9/XX9+vUk95k3b55mzZqlzz77TE2bNv3X45vNZsXFxT2xL23atDKZTKpVq5aaNGmi2bNnq0GDBipQoID8/Pzk7OysTz/91LL9jRs3NHjwYH388cfKnz+/5s+fry5dumj16tVyc3PTgwcP1KFDB127dk39+/fXG2+8oTVr1qhr166aO3euvLy8JEkDBw7Utm3b1LNnT5UqVUrbtm3TkCFDlC5dOvXq1Us3btzQ0aNHFRgYqPz588tsNsvX11f79u1Tnz595OLiok2bNql///6KjY3Ve++9J0maPHmyFi9ebDnuTz/9pC+//PI5/0QAAMCrRAAEAABeSwsXLlR8fLzmzJmj7NmzS5LefvvtJBdoXrFihSZPnqyxY8fq/ffff+rx9+zZoxIlSjyxb/r06apXr54kafjw4fr99981duxYVapUSceOHdPy5cut1gmKiYnR6NGjLYFLpUqVVLt2bc2ZM0dTp07V+vXrdfz4ca1atUqlSpWSJFWvXl3t2rWTv7+/1qxZo/DwcG3cuFHDhg1Thw4dJEleXl46f/68QkJC1KhRI2XPnl329vaWW9d27dqlHTt2aOrUqWrQoIEkqVq1aoqJiZG/v78aNWqk6OhoLVmyRJ06ddLHH39s2ebKlSvasWPHUz8nAACQMgiAAADAayksLEylS5e2hD+SVKpUKb355puJtv3111919OhRlStX7pmf4FWiRAmNGTPmiX358+e3vHZyctK4cePUo0cPhYaGqlevXonWDrKzs1OjRo0s7x0dHVW9enVt375dkrR7927lypVLJUqUsJp1VLNmTU2aNEm3b99WWFiYJOmdd96xOva/PeFs9+7dMplMqlGjhtVxfXx8tGHDBv3555+6evWqHj58qJo1a1rtW79+fQIgAABSEQIgAADwWrp9+7by5s2bqD1XrlyJ2o4cOSJvb29t3bpVW7ZskY+Pz1OPnzFjRnl4eDxTLZUrV9Ybb7yhK1euJApSJClnzpyys7P+z7YcOXLo1q1bkh6t/3P16tUkZxxdvXrVsm2OHDmeqabHxzWbzSpTpswT+69cuaI7d+5IkrJly2bV96TPEQAA2A4BEAAAeC1ly5ZN165dS9T+OCj5uw8++EBjxozRhx9+qDFjxqhChQrKlClTstUSGBioW7duqVChQho+fLhWr16tdOnS/WtN165ds4Q5mTNnVsGCBeXv7//E4+fNm1dZsmSR9Gg9ody5c1v6Tp48qVu3bqls2bKJ9sucObMyZMigxYsXP/G4BQoU0KFDhyRJ169fV6FChf61ZgAAYDs8BQwAALyWKlWqpP379+vy5cuWtr/++kvnzp1LtG2uXLlkMpk0evRoXbt2LVkXOD506JDmzp2rnj17avLkyQoPD9dXX31ltc39+/etbqe6f/++tm/fblncuUKFCrp48aJy5MghDw8Py8+uXbs0d+5cpU2b1hLwbNmyxerY/v7++vzz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",
      "text/plain": [
       "<Figure size 1158.25x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluator.plot_model_comparison([\"generated_answer\", \"ft_generated_answer\"], scenario=\"idk_expected\", nice_names=[\"Baseline\", \"Fine-Tuned\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that the fine-tuned model has learnt to say \"I don't know\" a lot better than the prompt. Or, the model has gotten good at skipping questions.\n",
    "\n",
    "### Observations\n",
    "\n",
    "1. The fine-tuned model is better at saying \"I don't know\"\n",
    "2. Hallucinations drop from 100% to 15% with fine-tuning\n",
    "3. Wrong answers drop from 17% to 6% with fine-tuning\n",
    "\n",
    "**Correct answers also drop from 83% to 60% with fine-tuning** - this is because the fine-tuned model is **more conservative** and says \"I don't know\" more often. This is a good thing because it's better to say \"I don't know\" than to give a wrong answer.\n",
    "\n",
    "That said, we want to improve the correctness of the model, even if that increases the hallucinations. We're looking for a model that is both correct and conservative, striking a balance between the two. We'll use Qdrant and Few-Shot Learning to achieve this."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**💪 You're 2/3rds of the way there! Keep reading!**\n",
    "\n",
    "# Section B: Few Shot Learning\n",
    "\n",
    "We'll select a few examples from the dataset, including cases where the answer is not present in the context. We'll then use these examples to create a prompt that we can use to fine-tune the model. We'll then measure the performance of the fine-tuned model.\n",
    "\n",
    "**What is next?**\n",
    "\n",
    "6. Fine-Tuning OpenAI Model with Qdrant\n",
    "    6.1 Embed the Fine-Tuning Data\n",
    "    6.2 Embedding the Questions\n",
    "7. Using Qdrant to Improve RAG Prompt\n",
    "8. Evaluation\n",
    "\n",
    "\n",
    "## 6. Fine-Tuning OpenAI Model with Qdrant\n",
    "\n",
    "So far, we've been using the OpenAI model to answer questions without using examples of the answer. The previous step made it work better on in-context examples, while this one helps it generalize to unseen data, and attempt to learn when to say \"I don't know\" and when to give an answer.\n",
    "\n",
    "This is where few-shot learning comes in!\n",
    "\n",
    "Few-shot learning is a type of transfer learning that allows us to answer questions where the answer is not present in the context. We can do this by providing a few examples of the answer we're looking for, and the model will learn to answer questions where the answer is not present in the context."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.1 Embed the Training Data\n",
    "\n",
    "Embeddings are a way to represent sentences as an array of floats. We'll use the embeddings to find the most similar questions to the ones we're looking for."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from qdrant_client import QdrantClient\n",
    "from qdrant_client.http import models\n",
    "from qdrant_client.http.models import PointStruct\n",
    "from qdrant_client.http.models import Distance, VectorParams"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we've the Qdrant imports in place, "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "qdrant_client = QdrantClient(\n",
    "    url=os.getenv(\"QDRANT_URL\"), api_key=os.getenv(\"QDRANT_API_KEY\"), timeout=6000, prefer_grpc=True\n",
    ")\n",
    "\n",
    "collection_name = \"squadv2-cookbook\"\n",
    "\n",
    "# # Create the collection, run this only once\n",
    "# qdrant_client.recreate_collection(\n",
    "#     collection_name=collection_name,\n",
    "#     vectors_config=VectorParams(size=384, distance=Distance.COSINE),\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fastembed.embedding import DefaultEmbedding\n",
    "from typing import List\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from tqdm.notebook import tqdm\n",
    "\n",
    "tqdm.pandas()\n",
    "\n",
    "embedding_model = DefaultEmbedding()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.2 Embedding the Questions\n",
    "\n",
    "Next, you'll embed the entire training set questions. You'll use the question to question similarity to find the most similar questions to the question we're looking for. This is a workflow which is used in RAG to leverage the OpenAI model ability of incontext learning with more examples. This is what we call Few Shot Learning here.\n",
    "\n",
    "**❗️⏰ Important Note: This step can take up to 3 hours to complete. Please be patient. If you see Out of Memory errors or Kernel Crashes, please reduce the batch size to 32, restart the kernel and run the notebook again. This code needs to be run only ONCE.**\n",
    "\n",
    "## Function Breakdown for `generate_points_from_dataframe`\n",
    "\n",
    "1. **Initialization**: `batch_size = 512` and `total_batches` set the stage for how many questions will be processed in one go. This is to prevent memory issues. If your machine can handle more, feel free to increase the batch size. If your kernel crashes, reduce the batch size to 32 and try again.\n",
    "2. **Progress Bar**: `tqdm` gives you a nice progress bar so you don't fall asleep.\n",
    "3. **Batch Loop**: The for-loop iterates through batches. `start_idx` and `end_idx` define the slice of the DataFrame to process.\n",
    "4. **Generate Embeddings**: `batch_embeddings = embedding_model.embed(batch, batch_size=batch_size)` - This is where the magic happens. Your questions get turned into embeddings.\n",
    "5. **PointStruct Generation**: Using `.progress_apply`, it turns each row into a `PointStruct` object. This includes an ID, the embedding vector, and other metadata.\n",
    "\n",
    "Returns the list of `PointStruct` objects, which can be used to create a collection in Qdrant."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_points_from_dataframe(df: pd.DataFrame) -> List[PointStruct]:\n",
    "    batch_size = 512\n",
    "    questions = df[\"question\"].tolist()\n",
    "    total_batches = len(questions) // batch_size + 1\n",
    "    \n",
    "    pbar = tqdm(total=len(questions), desc=\"Generating embeddings\")\n",
    "    \n",
    "    # Generate embeddings in batches to improve performance\n",
    "    embeddings = []\n",
    "    for i in range(total_batches):\n",
    "        start_idx = i * batch_size\n",
    "        end_idx = min((i + 1) * batch_size, len(questions))\n",
    "        batch = questions[start_idx:end_idx]\n",
    "        \n",
    "        batch_embeddings = embedding_model.embed(batch, batch_size=batch_size)\n",
    "        embeddings.extend(batch_embeddings)\n",
    "        pbar.update(len(batch))\n",
    "        \n",
    "    pbar.close()\n",
    "    \n",
    "    # Convert embeddings to list of lists\n",
    "    embeddings_list = [embedding.tolist() for embedding in embeddings]\n",
    "    \n",
    "    # Create a temporary DataFrame to hold the embeddings and existing DataFrame columns\n",
    "    temp_df = df.copy()\n",
    "    temp_df[\"embeddings\"] = embeddings_list\n",
    "    temp_df[\"id\"] = temp_df.index\n",
    "    \n",
    "    # Generate PointStruct objects using DataFrame apply method\n",
    "    points = temp_df.progress_apply(\n",
    "        lambda row: PointStruct(\n",
    "            id=row[\"id\"],\n",
    "            vector=row[\"embeddings\"],\n",
    "            payload={\n",
    "                \"question\": row[\"question\"],\n",
    "                \"title\": row[\"title\"],\n",
    "                \"context\": row[\"context\"],\n",
    "                \"is_impossible\": row[\"is_impossible\"],\n",
    "                \"answers\": row[\"answers\"],\n",
    "            },\n",
    "        ),\n",
    "        axis=1,\n",
    "    ).tolist()\n",
    "\n",
    "    return points\n",
    "\n",
    "points = generate_points_from_dataframe(train_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Upload the Embeddings to Qdrant\n",
    "\n",
    "Note that configuring Qdrant is outside the scope of this notebook. Please refer to the [Qdrant](https://qdrant.tech) for more information. We used a timeout of 600 seconds for the upload, and grpc compression to speed up the upload."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "operation_info = qdrant_client.upsert(\n",
    "    collection_name=collection_name, wait=True, points=points\n",
    ")\n",
    "print(operation_info)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Using Qdrant to Improve RAG Prompt\n",
    "\n",
    "Now that we've uploaded the embeddings to Qdrant, we can use Qdrant to find the most similar questions to the question we're looking for. We'll use the top 5 most similar questions to create a prompt that we can use to fine-tune the model. We'll then measure the performance of the fine-tuned model on the same validation set, but with few shot prompting!\n",
    "\n",
    "Our main function `get_few_shot_prompt` serves as the workhorse for generating prompts for few-shot learning. It does this by retrieving similar questions from Qdrant - a vector search engine, using an embeddings model. Here is the high-level workflow:\n",
    "\n",
    "1. Retrieve similar questions from Qdrant where the **answer is present** in the context\n",
    "2. Retrieve similar questions from Qdrant where the **answer is IMPOSSIBLE** i.e. the expected answer is \"I don't know\" to find in the context\n",
    "3. Create a prompt using the retrieved questions\n",
    "4. Fine-tune the model using the prompt\n",
    "5. Evaluate the fine-tuned model on the validation set with the same prompting technique"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_few_shot_prompt(row):\n",
    "\n",
    "    query, row_context = row[\"question\"], row[\"context\"]\n",
    "\n",
    "    embeddings = list(embedding_model.embed([query]))\n",
    "    query_embedding = embeddings[0].tolist()\n",
    "\n",
    "    num_of_qa_to_retrieve = 5\n",
    "\n",
    "    # Query Qdrant for similar questions that have an answer\n",
    "    q1 = qdrant_client.search(\n",
    "        collection_name=collection_name,\n",
    "        query_vector=query_embedding,\n",
    "        with_payload=True,\n",
    "        limit=num_of_qa_to_retrieve,\n",
    "        query_filter=models.Filter(\n",
    "            must=[\n",
    "                models.FieldCondition(\n",
    "                    key=\"is_impossible\",\n",
    "                    match=models.MatchValue(\n",
    "                        value=False,\n",
    "                    ),\n",
    "                ),\n",
    "            ],\n",
    "        )\n",
    "    )\n",
    "\n",
    "    # Query Qdrant for similar questions that are IMPOSSIBLE to answer\n",
    "    q2 = qdrant_client.search(\n",
    "        collection_name=collection_name,\n",
    "        query_vector=query_embedding,\n",
    "        query_filter=models.Filter(\n",
    "            must=[\n",
    "                models.FieldCondition(\n",
    "                    key=\"is_impossible\",\n",
    "                    match=models.MatchValue(\n",
    "                        value=True,\n",
    "                    ),\n",
    "                ),\n",
    "            ]\n",
    "        ),\n",
    "        with_payload=True,\n",
    "        limit=num_of_qa_to_retrieve,\n",
    "    )\n",
    "\n",
    "\n",
    "    instruction = \"\"\"Answer the following Question based on the Context only. Only answer from the Context. If you don't know the answer, say 'I don't know'.\\n\\n\"\"\"\n",
    "    # If there is a next best question, add it to the prompt\n",
    "    \n",
    "    def q_to_prompt(q):\n",
    "        question, context = q.payload[\"question\"], q.payload[\"context\"]\n",
    "        answer = q.payload[\"answers\"][0] if len(q.payload[\"answers\"]) > 0 else \"I don't know\"\n",
    "        return [\n",
    "            {\n",
    "                \"role\": \"user\", \n",
    "                \"content\": f\"\"\"Question: {question}\\n\\nContext: {context}\\n\\nAnswer:\"\"\"\n",
    "            },\n",
    "            {\"role\": \"assistant\", \"content\": answer},\n",
    "        ]\n",
    "\n",
    "    rag_prompt = []\n",
    "    \n",
    "    if len(q1) >= 1:\n",
    "        rag_prompt += q_to_prompt(q1[1])\n",
    "    if len(q2) >= 1:\n",
    "        rag_prompt += q_to_prompt(q2[1])\n",
    "    if len(q1) >= 1:\n",
    "        rag_prompt += q_to_prompt(q1[2])\n",
    "    \n",
    "    \n",
    "\n",
    "    rag_prompt += [\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": f\"\"\"Question: {query}\\n\\nContext: {row_context}\\n\\nAnswer:\"\"\"\n",
    "        },\n",
    "    ]\n",
    "\n",
    "    rag_prompt = [{\"role\": \"system\", \"content\": instruction}] + rag_prompt\n",
    "    return rag_prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ⏰ Time: 2 min\n",
    "train_sample[\"few_shot_prompt\"] = train_sample.progress_apply(get_few_shot_prompt, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7. Fine-Tuning OpenAI Model with Qdrant\n",
    "\n",
    "### 7.1 Upload the Fine-Tuning Data to OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Prepare the OpenAI File format i.e. JSONL from train_sample\n",
    "def dataframe_to_jsonl(df):\n",
    "    def create_jsonl_entry(row):\n",
    "        messages = row[\"few_shot_prompt\"]\n",
    "        return json.dumps({\"messages\": messages})\n",
    "\n",
    "    jsonl_output = df.progress_apply(create_jsonl_entry, axis=1)\n",
    "    return \"\\n\".join(jsonl_output)\n",
    "\n",
    "with open(\"local_cache/100_train_few_shot.jsonl\", \"w\") as f:\n",
    "    f.write(dataframe_to_jsonl(train_sample))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7.2 Fine-Tune the Model\n",
    "\n",
    "⏰ **Time to run: ~15-30 minutes**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fine_tuner = OpenAIFineTuner(\n",
    "        training_file_path=\"local_cache/100_train_few_shot.jsonl\",\n",
    "        model_name=\"gpt-3.5-turbo\",\n",
    "        suffix=\"trnfewshot20230907\"\n",
    "    )\n",
    "\n",
    "model_id = fine_tuner.fine_tune_model()\n",
    "model_id"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's try this out\n",
    "completion = client.chat.completions.create(\n",
    "    model=model_id,\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Can you answer the following question based on the given context? If not, say, I don't know:\\n\\nQuestion: What is the capital of France?\\n\\nContext: The capital of Mars is Gaia. Answer:\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"assistant\",\n",
    "            \"content\": \"I don't know\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Question: Where did Maharana Pratap die?\\n\\nContext: Rana Pratap's defiance of the mighty Mughal empire, almost alone and unaided by the other Rajput states, constitute a glorious saga of Rajput valour and the spirit of self sacrifice for cherished principles. Rana Pratap's methods of guerrilla warfare was later elaborated further by Malik Ambar, the Deccani general, and by Emperor Shivaji.\\nAnswer:\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"assistant\",\n",
    "            \"content\": \"I don't know\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Question: Who did Rana Pratap fight against?\\n\\nContext: In stark contrast to other Rajput rulers who accommodated and formed alliances with the various Muslim dynasties in the subcontinent, by the time Pratap ascended to the throne, Mewar was going through a long standing conflict with the Mughals which started with the defeat of his grandfather Rana Sanga in the Battle of Khanwa in 1527 and continued with the defeat of his father Udai Singh II in Siege of Chittorgarh in 1568. Pratap Singh, gained distinction for his refusal to form any political alliance with the Mughal Empire and his resistance to Muslim domination. The conflicts between Pratap Singh and Akbar led to the Battle of Haldighati. Answer:\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"assistant\",\n",
    "            \"content\": \"Akbar\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Question: Which state is Chittorgarh in?\\n\\nContext: Chittorgarh, located in the southern part of the state of Rajasthan, 233 km (144.8 mi) from Ajmer, midway between Delhi and Mumbai on the National Highway 8 (India) in the road network of Golden Quadrilateral. Chittorgarh is situated where National Highways No. 76 & 79 intersect. Answer:\",\n",
    "        },\n",
    "    ],\n",
    ")\n",
    "print(\"Correct Answer: Rajasthan\\nModel Answer:\")\n",
    "print(completion.choices[0].message)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "⏰ **Time to run: 5-15 min**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"ft_generated_answer_few_shot\"] = df.progress_apply(answer_question, model=model_id, prompt_func=get_few_shot_prompt, axis=1)\n",
    "df.to_json(\"local_cache/100_val_ft_few_shot.json\", orient=\"records\", lines=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8. Evaluation\n",
    "\n",
    "But how well does the model perform? Let's compare the results from the 3 different models we've looked at so far:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 203,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABK0AAAH4CAYAAACIQh4xAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAACK50lEQVR4nOzdd3zN5///8efJFiMxWjViRxAiqRExQ6gQNVvVmrXKxww1a++9Yu8RasaqWqW2SqlZSquxi9jRkERyfn/4Od+eilEk55DH/XbL7ZNc7/f7er+uc9714Znruo7BaDQaBQAAAAAAAFgRG0sXAAAAAAAAAPwboRUAAAAAAACsDqEVAAAAAAAArA6hFQAAAAAAAKwOoRUAAAAAAACsDqEVAAAAAAAArA6hFQAAAAAAAKwOoRUAAAAAAACsDqEVAAAAkMyMRqOlSwAAwOoRWgEAALyDunbtKg8PD82dO9fSpSSJkJAQeXh4PPcrJibG0mU+5erVq2rdurUuX7782n1dunRJHh4eCgsLewOVAQBgfewsXQAAAADerKioKP3www/Knz+/li1bpi+//FIGg8HSZSWJZcuWPfOYg4NDMlbycvbt26edO3daugwAAN4KhFYAAADvmO+++06S9M0336hp06b66aef5OfnZ+Gqkoa3t7elSwAAAEmE5YEAAADvmFWrVsnPz0+lSpVSzpw5tXTpUrPjjRs31jfffKOZM2fK399fRYoUUYMGDXTs2DHTOQ8fPtSAAQNUvnx5FS5cWIGBgZozZ44k6bfffpOHh4e2bt1qOv/gwYPy8PDQhAkTTG23b99WwYIFTSHanTt31K9fP5UuXVpFihRR/fr1tX//frPaPDw8NHnyZNWtW1deXl6aPHnya70Wf/31l4oVK6bGjRub2mJiYlS9enUFBQUpJiZGBw4ckIeHh/bs2aOGDRvKy8tLH330kZYsWWLWV0JCgmbOnKkqVaqocOHCqlq1qhYtWvTUPdesWaM6deqoaNGi8vf319ixYxUbG6uwsDD16tVLkhQQEKCePXuarlmxYoWCgoJUuHBh+fv7KyQkRPHx8Wb9btmyRTVr1pSXl5fq1Kmj33777bVeGwAArB2hFQAAwDvk999/1/Hjx1W7dm1JUu3atbVt2zbduHHD7LzNmzdr27Zt6tOnj8aNG6cbN26oQ4cOpqBk2LBh2rVrl3r06KE5c+YoICBAo0aN0qpVq1SgQAFlyZJF+/btM/X3JHw6ePCgqW3v3r2ysbFRuXLlFBMTo6ZNm2rbtm0KDg7W5MmT9cEHH6hly5ZPBVfTp0/Xxx9/rEmTJqlq1arPHe+jR48S/UpISJAkZcmSRT179lR4eLhWrVolSRo7dqwuXLigsWPHytHR0dRXcHCwChUqpClTpqh06dIaOHCgWXA1YMAATZo0STVr1tT06dMVGBioYcOGacqUKaZzFi9erB49esjT01OTJ09W69attWjRIg0ZMkT+/v5q27atJGny5Mn63//+J0maMWOG+vbtKz8/P02fPl0NGzbUrFmz1LdvX1O/27dvV8eOHeXh4aEpU6aoWrVq6tat23NfGwAA3nYsDwQAAHiHrFq1Sq6urqpUqZIkqU6dOgoJCdHKlSvVpk0b03mPHj3SnDlzlCZNGknS33//rR49eujUqVMqXLiwwsPDVaZMGQUFBUmSfH195ezsrIwZM0qSypcv/1Ro5enpqaNHjyomJkaOjo7avXu3PvzwQ7m4uGj58uX67bfftHz5chUtWtTUR+PGjTVmzBhToCRJxYsX15dffvlS4/X09Ey0vWHDhurXr58k6dNPP9WWLVs0atQoubq6auHCherWrZsKFChgdk2VKlX0zTffSJLKlSun69eva+rUqfr888917tw5LV++XF26dFHr1q0lSWXLlpXBYNCMGTP0xRdfyMXFRVOmTFHlypU1ZMgQU78PHjzQhg0blDZtWuXIkUOSVLBgQWXPnl1RUVGaOnWqPvvsM/Xp08fUr6urq/r06aMvv/xS7u7umjJliry8vDR69GhTfdLjAA4AgHcVM60AAADeEXFxcVq3bp0qV66shw8f6t69e0qdOrWKFSum5cuXm2YfSVK+fPlMgZUkZc6cWdLjgEV6HFItX75crVq1UmhoqC5evKh27drJ399fkuTv769z587pr7/+UnR0tI4dO6Y2bdooNjZWR48eldFo1J49e0zn79+/X++99548PT1Ns6Hi4+NVsWJFnThxQnfv3jXVUrBgwZce88qVKxP9atmypdl5Q4YMUUJCgtq3b6+SJUuqefPmT/VVp04ds58/+ugjRUZGKiIiQj/99JOMRqMqVapkNqOrUqVKiomJ0aFDhxQREaGbN2+qSpUqZv20aNFCYWFhsre3f+qehw8f1sOHDxPt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x//88085OjoqZ86cT/0y7NChQ0qXLp1atmxpavv777916NAh2dn9XwRiY2NjFlA92Y/q6tWrypEjhyTp7NmzunPnjumc+fPna8GCBdq8ebMcHBzk5+enwoULa+PGjbpy5cobGz/+z0uHViVLlnzmsZiYGDk4ODAVDvgPLl+5p4jztyxdBgDgDTIajXrw4IGMRqOlSwGSHM87gKRia2urAQMGqF27dqpXr54aNmyovHnz6sGDB9q7d68WL16sTp06ycXFRenSpdONGze0c+dOFSxYUF5eXvr22281YsQIVaxYUdevX9ecOXN048YNubi4mO6RLl06HT58WPv371ehQoXk6+srJycnjRgxQp06ddLff/+tSZMmydXV1XRNqVKlNGbMGLVr106NGjWSra2tli5dKgcHB1WsWNECr9S775Xn5//555/q3LmzSpYsKR8fH508eVIDBw7UokWL3mR9AAAAAAAghfH399fy5cuVP39+TZ8+XS1atFCXLl106tQpjR8/Xq1bt5Yk1a1bV9myZVO7du20Zs0a1alTR+3atdPGjRvVqlUrTZo0ScWLF9egQYN0584dnT17VpLUsGFD2dvbq1WrVtq1a5fSpUunkJAQxcfHq127dpo4caLatWunwoULm2oqUKCApk+frvv376tLly5q37697ty5o7lz5ypPHrZ/SQoG4yv8auTUqVNq2LChMmbMqPLly2vJkiVauXKlVq9ercWLF2vYsGGqU6dOUtQLvPWerKNevOIiM60ApCi5c2bQiEHVLV1GkoqOjtapU6dUsGBBOTvzYRt4t/G8I6XhmUdKEx0dbfFn/aWXB/7TyJEjVbhwYc2dO1eStHjxYklSnz59FBMTo4ULFxJaAQAAAAAA4JW90vLAI0eOqFmzZrKzs3tqH6vq1avr3Llzb6I2AAAAAAAApFCvFFo5Ojrq4cOHiR67c+eOHBwcXqsoAAAAAAAApGyvFFqVKVNGkyZN0tWrV01tBoNBf//9t+bOnavSpUu/sQIBAAAAAACQ8rzSnlbdunXTZ599psDAQBUoUEAGg0EjRoxQRESEjEajxo0b96brBAAAAAAAQArySjOtsmTJorVr16pp06YyGo3KkSOHoqOjVaNGDYWFhcnNze1N1wkAAAAAAIAU5JVmWklS+vTpFRwc/CZrAQAASFIJCQmaN2+eli1bpqtXrypX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",
      "text/plain": [
       "<Figure size 1203.25x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluator = Evaluator(df)\n",
    "evaluator.plot_model_comparison([\"generated_answer\", \"ft_generated_answer\", \"ft_generated_answer_few_shot\"], scenario=\"answer_expected\", nice_names=[\"Baseline\", \"Fine-Tuned\", \"Fine-Tuned with Few-Shot\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is quite amazing -- we're able to get the best of both worlds! We're able to get the model to be both correct and conservative: \n",
    "\n",
    "1. The model is correct 83% of the time -- this is the same as the base model\n",
    "2. The model gives the wrong answer only 8% of the time -- down from 17% with the base model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, let's look at the hallucinations. We want to reduce the hallucinations, but not at the cost of correctness. We want to strike a balance between the two. We've struck a good balance here:\n",
    "\n",
    "1. The model hallucinates 53% of the time -- down from 100% with the base model\n",
    "2. The model says \"I don't know\" 47% of the time -- up from NEVER with the base model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 202,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1158.25x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "evaluator.plot_model_comparison([\"generated_answer\", \"ft_generated_answer\", \"ft_generated_answer_few_shot\"], scenario=\"idk_expected\", nice_names=[\"Baseline\", \"Fine-Tuned\", \"Fine-Tuned with Few-Shot\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Few Shot Fine-Tuning with Qdrant is a great way to control and steer the performance of your RAG system. Here, we made the model less conservative compared to zero shot and more confident by using Qdrant to find similar questions. \n",
    "\n",
    "You can also use Qdrant to make the model more conservative. We did this by giving examples of questions where the answer is not present in the context.  \n",
    "This is biasing the model to say \"I don't know\" more often. \n",
    "\n",
    "Similarly, one can also use Qdrant to make the model more confident by giving examples of questions where the answer is present in the context. This biases the model to give an answer more often. The trade-off is that the model will also hallucinate more often.\n",
    "\n",
    "You can make this trade off by adjusting the training data: distribution of questions and examples, as well as the kind and number of examples you retrieve from Qdrant.\n",
    "\n",
    "## 9. Conclusion\n",
    "\n",
    "In this notebook, we've demonstrated how to fine-tune OpenAI models for specific use-cases. We've also demonstrated how to use Qdrant and Few-Shot Learning to improve the performance of the model.\n",
    "\n",
    "### Aggregate Results\n",
    "\n",
    "So far, we've looked at the results for each scenario separately, i.e. each scenario summed to 100. Let's look at the results as an aggregate to get a broader sense of how the model is performing:\n",
    "\n",
    "| Category | Base | Fine-Tuned | Fine-Tuned with Qdrant |\n",
    "| --- | --- | --- | --- |\n",
    "| Correct | 44% | 32% | 44% |\n",
    "| Skipped | 0% | 18% | 5% |\n",
    "| Wrong | 9% | 3% | 4% |\n",
    "| Hallucination | 47% | 7% | 25% |\n",
    "| I don't know | 0% | 40% | 22% |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Observations\n",
    "\n",
    "#### Compared to base model\n",
    "1. The few shot fine-tuned with Qdrant model is as good as the base model at answering questions where the answer is present in the context. \n",
    "2. The few shot fine-tuned with Qdrant model is better at saying \"I don't know\" when the answer is not present in the context.\n",
    "3. The few shot fine-tuned with Qdrant model is better at reducing hallucinations.\n",
    "\n",
    "\n",
    "#### Compared to fine-tuned model\n",
    "1. The few shot fine-tuned with Qdrant model gets more correct answers than the fine-tuned model: **83% of the questions are answered correctly vs 60%** for the fine-tuned model\n",
    "2. The few shot fine-tuned with Qdrant model is better at deciding when to say \"I don't know\" when the answer is not present in the context. **34% skip rate for the plain fine-tuning mode, vs 9% for the few shot fine-tuned with Qdrant model**\n",
    "\n",
    "\n",
    "Now, you should be able to:\n",
    "\n",
    "1. Notice the trade-offs between number of correct answers and hallucinations -- and how training dataset choice influences that!\n",
    "2. Fine-tune OpenAI models for specific use-cases and use Qdrant to improve the performance of your RAG model\n",
    "3. Get started on how to evaluate the performance of your RAG model"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "fst",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.17"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
